<template>
  <div class="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50 py-8">
    <div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
      <div class="flex flex-col lg:flex-row gap-6">
        <main class="flex-1 bg-white p-6 rounded-lg shadow">
          <h1 class="text-2xl font-bold mb-2">接瓶子比手速</h1>
          <p class="text-sm text-gray-600 mb-4">在限定时间内点击下落的瓶子，每点击一个得 5 分。难度：15s / 10s / 5s（最简单为 15s，默认总瓶数 20 个，随机位置下落）。</p>

          <div class="mb-4 flex flex-col sm:flex-row items-start sm:items-center gap-3">
            <label class="flex items-center gap-2">
              <span class="text-sm">难度：</span>
              <select v-model.number="selectedTime" class="border rounded px-2 py-1">
                <option :value="15">简单（15s）</option>
                <option :value="10">普通（10s）</option>
                <option :value="5">困难（5s）</option>
              </select>
            </label>

            <div class="flex items-center gap-2">
              <button @click="startGame" :disabled="running" class="px-4 py-2 bg-indigo-600 text-white rounded">开始</button>
              <button @click="resetGame" class="px-3 py-2 bg-gray-200 rounded">重置</button>
            </div>

            <div class="ml-auto flex items-center gap-4">
              <div class="text-sm">时间：<span class="font-medium">{{ timeLeftDisplay }}</span></div>
              <div class="text-sm">得分：<span class="font-bold text-indigo-600">{{ score }}</span></div>
            </div>
          </div>

          <div ref="playArea" class="relative bg-slate-50 rounded-lg border border-dashed border-gray-200 h-96 overflow-hidden touch-none">
            <div v-if="!running && !ended" class="absolute inset-0 flex items-center justify-center text-gray-400">点击开始后瓶子会随机下落，点击瓶子得分</div>

            <!-- bottles -->
            <div v-for="b in bottles" :key="b.id" @click.stop="hitBottle(b.id)"
                 class="absolute w-12 h-16 flex items-center justify-center cursor-pointer"
                 :style="{ left: b.left + '%', transform: 'translateX(-50%)', top: b.top + 'px' }">
              <div class="w-10 h-14 bg-gradient-to-b from-white to-green-300 rounded-md shadow flex items-center justify-center text-sm select-none">
                <span class="text-green-800 font-semibold">🍾</span>
              </div>
            </div>
          </div>

          <!-- end modal -->
          <div v-if="ended" class="mt-4 bg-white border rounded p-4">
            <h3 class="text-lg font-semibold">游戏结束</h3>
            <div class="mt-2">本次得分：<span class="font-bold text-indigo-600">{{ score }}</span></div>
            <div class="mt-3 flex items-center gap-2">
              <input v-model="playerName" placeholder="输入你的名字（用于排行榜，可选）" class="border rounded px-2 py-1" />
              <button @click="saveResult" class="px-3 py-1 bg-green-500 text-white rounded">保存到排行榜</button>
              <button @click="restart" class="px-3 py-1 bg-indigo-600 text-white rounded">再来一局</button>
            </div>
          </div>
        </main>

        <aside class="w-full lg:w-80 bg-white p-4 rounded-lg shadow max-h-[520px] overflow-hidden">
          <h2 class="text-lg font-semibold mb-3">排行榜</h2>
          <div class="text-xs text-gray-500 mb-3">排行榜按难度区分：简单（15s）、普通（10s）、困难（5s）。保存后会记录姓名、分数和时间。</div>

          <div class="mb-3 flex gap-2">
            <button @click="loadLeaderboard(15)" :class="leaderBtnClass(15)">简单</button>
            <button @click="loadLeaderboard(10)" :class="leaderBtnClass(10)">普通</button>
            <button @click="loadLeaderboard(5)" :class="leaderBtnClass(5)">困难</button>
          </div>

          <div class="overflow-y-auto" style="max-height:420px">
            <ul>
              <li v-for="(item, idx) in leaderboard" :key="item.ts" class="py-2 px-2 border-b last:border-b-0 flex items-center justify-between">
                <div>
                  <div class="font-medium">{{ item.name || '匿名' }}</div>
                  <div class="text-xs text-gray-500">{{ new Date(item.ts).toLocaleString() }}</div>
                </div>
                <div class="text-right">
                  <div class="font-semibold text-indigo-600">{{ item.score }}</div>
                  <div v-if="idx===0" class="text-xs text-red-500">第一名</div>
                </div>
              </li>
            </ul>

            <div v-if="leaderboard.length===0" class="text-center text-gray-400 py-8">暂无成绩，快来挑战！</div>
          </div>
        </aside>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'

const selectedTime = ref(15) // seconds
const totalBottles = 20
const playArea = ref(null)
const timeLeft = ref(0)
const running = ref(false)
const ended = ref(false)
const score = ref(0)
const bottles = ref([])
const spawnTimer = ref(null)
const rafId = ref(null)
const spawnIndex = ref(0)
const playerName = ref('')

const leaderboard = ref([])
let containerHeight = 0

const timeLeftDisplay = () => `${Math.ceil(timeLeft.value)}s`

function leaderBtnClass(t) {
  return `px-3 py-1 rounded ${selectedTime.value===t ? 'bg-indigo-600 text-white' : 'bg-gray-100'}`
}

function initContainer() {
  if (playArea.value) {
    containerHeight = playArea.value.getBoundingClientRect().height
  }
}

function startGame() {
  resetState()
  initContainer()
  timeLeft.value = selectedTime.value
  running.value = true
  ended.value = false
  spawnIndex.value = 0

  // spawn evenly over the selected time
  const spawnInterval = (selectedTime.value * 1000) / totalBottles
  spawnTimer.value = setInterval(() => {
    if (spawnIndex.value >= totalBottles) {
      clearInterval(spawnTimer.value)
      spawnTimer.value = null
      return
    }
    spawnBottle()
    spawnIndex.value++
  }, spawnInterval)

  // Start update loop
  let last = performance.now()
  function loop(now) {
    const dt = (now - last) / 1000
    last = now
    // update bottles
    for (let i = bottles.value.length - 1; i >= 0; i--) {
      const b = bottles.value[i]
      b.top += b.speed * dt
      if (b.top > containerHeight - 10) {
        // remove missed bottle
        bottles.value.splice(i, 1)
      }
    }
    // update timer
    timeLeft.value -= dt
    if (timeLeft.value <= 0) {
      timeLeft.value = 0
      endGame()
      return
    }
    rafId.value = requestAnimationFrame(loop)
  }
  rafId.value = requestAnimationFrame(loop)
}

function spawnBottle() {
  const id = Date.now() + Math.random()
  const left = 8 + Math.random() * 84 // percent
  const top = -80
  // speed px/s random
  const speed = 80 + Math.random() * 160
  bottles.value.push({ id, left, top, speed })
}

function hitBottle(id) {
  const idx = bottles.value.findIndex(b => b.id === id)
  if (idx === -1) return
  bottles.value.splice(idx, 1)
  score.value += 5
}

function endGame() {
  running.value = false
  ended.value = true
  if (spawnTimer.value) {
    clearInterval(spawnTimer.value)
    spawnTimer.value = null
  }
  if (rafId.value) {
    cancelAnimationFrame(rafId.value)
    rafId.value = null
  }
}

function resetState() {
  score.value = 0
  bottles.value = []
  timeLeft.value = 0
  ended.value = false
}

function resetGame() {
  if (spawnTimer.value) {
    clearInterval(spawnTimer.value)
    spawnTimer.value = null
  }
  if (rafId.value) {
    cancelAnimationFrame(rafId.value)
    rafId.value = null
  }
  running.value = false
  resetState()
}

function restart() {
  resetGame()
  startGame()
}

async function saveResult() {
  try {
    await $fetch('/api/catch-bottle/submit', {
      method: 'POST',
      body: { name: playerName.value || '匿名', score: score.value, time: selectedTime.value }
    })
    await loadLeaderboard(selectedTime.value)
    alert('成绩已保存')
  } catch (err) {
    alert('保存失败: ' + String(err))
  }
}

async function loadLeaderboard(t = selectedTime.value) {
  selectedTime.value = t
  try {
    const res = await $fetch('/api/catch-bottle/list?time=' + t + '&limit=50')
    if (Array.isArray(res)) {
      leaderboard.value = res.map(r => ({ ...r }))
    } else {
      leaderboard.value = []
    }
  } catch (err) {
    // fallback to empty
    leaderboard.value = []
  }
}

onMounted(() => {
  initContainer()
  loadLeaderboard(selectedTime.value)
  window.addEventListener('resize', initContainer)
})

onBeforeUnmount(() => {
  if (spawnTimer.value) clearInterval(spawnTimer.value)
  if (rafId.value) cancelAnimationFrame(rafId.value)
  window.removeEventListener('resize', initContainer)
})
</script>

<style scoped>
/* Minimal custom styles - layout uses Tailwind */
</style>
